#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define SIZE 5
struct listnode {
	char date[SIZE] = "0";
	struct listnode *nextptr;

};
typedef struct listnode Listnode;
typedef Listnode *listnodeptr;

int bigOrSmall(char *s1, char *s2);
char dele(listnodeptr *sptr, char* value);
void instructions(void);
void printlist(listnodeptr currentptr);
int isempty(listnodeptr sptr);
void insert(listnodeptr *sptr, char* value)//插入和新建链表
{
	listnodeptr newptr = (listnodeptr)malloc(sizeof(Listnode));//分配内存空间
	if (newptr != NULL)//当有内存空间时
	{
		strcpy(newptr->date, value);//为新表赋值表的编号
		newptr->nextptr = NULL;//尾地址为NULL

		listnodeptr previousptr = NULL;//保存路标
		listnodeptr currentptr = *sptr;//用来循环的查找头地址
									   //插入查找循环
		while (currentptr != NULL && bigOrSmall(value, currentptr->date))//当没从头地址循环到最尾NULL时，以及新编号大于大于旧编号时
		{
			previousptr = currentptr;//保存路标
			currentptr = currentptr->nextptr;//进入下一层链表			

		}
		if (previousptr == NULL)//当没有进行循环（第一个表，或者链表编号数值最小）
		{

			if ((currentptr != NULL && *value != *currentptr->date) || currentptr == NULL)
			{
				newptr->nextptr = *sptr;//将原先头文件的地址放在自己的尾巴
				*sptr = newptr;//将自己地址放入头文件指针
			}
			else
			{
				printf("%s\n", "have same word");//重复字母或数字
			}
		}
		else//需要插入
		{
			if ((currentptr != NULL && value != currentptr->date) || currentptr == NULL)
			{
				previousptr->nextptr = newptr;//将新编号的地址放入刚刚（最小于）小于他的地址的尾巴
				newptr->nextptr = currentptr;//将新编号地址的尾巴指向刚刚大于他的链表地址
			}
			else
			{
				printf("%s\n", "have same word");//重复字母或数字
			}

		}

	}
	else
	{
		printf("%c not inserted\n", value);//内存空间不够

	}
}


int main(void)
{
	listnodeptr startptr = NULL;  //头地址初始化为NULL
	char item[SIZE] = "0";//链表编号初始化
	instructions();//输出菜单提示文字
	puts("?");//叫你输入了
	int choice;//初始化菜单选项
	scanf_s("%d", &choice, 0);//输入菜单选项
	while (choice != 3)//当菜单选项不是3（结束时）
	{
		switch (choice)
		{
		case 1://（插入和新建链表）
			printf("%s", "enter a character or number :");//输出提示文字
			scanf_s("\n%s", item, SIZE);//获取菜单编号
			insert(&startptr, item);//插入函数
			printlist(startptr);//输出函数
			break;
		case 2://（删除函数）
			if (!isempty(startptr))//当头地址不是空时
			{
				printf("%s", "enter character or number to be deleted :");
				scanf_s("\n%s", &item, SIZE);//获取要删除的链表编号
				if (dele(&startptr, item))//当成功删除时
				{
					printf("%s deleted.\n", item);//已删除
					printlist(startptr);//输出现存的链表结构
				}
			}
			else
			{
				printf("the line is empty\n");//找不到相关选项

			}
			break;
		default://输入declude(1,2,3)的字符时
			puts("invalid choice.\n");
			instructions();//输出提示菜单
			break;
		}

		puts("?");//叫你输入
		scanf_s("%d", &choice, 1);//回到循环选项

	}
	puts("end of run");//不玩了
	getchar();//停留
	return 0;
}

void instructions(void)//输出提示菜单函数
{
	puts("enter your choice\n\
		 		 1 to insert an element into the list.\n\
				 2 to delete an element from the list .\n\
				 3 to end\n\
								 		");//1是新增和插入链表，2是删除链表,3是结束程序
}
char dele(listnodeptr *sptr, char * value)//删除函数，delete，因为撞关键词所以改了
{
	if (*value == *(*sptr)->date)//当输入值等于链表头部编号时
	{
		listnodeptr temptr = *sptr;
		*sptr = (*sptr)->nextptr;//将头地址指针指向原先头地址的尾巴
		free(temptr);//释放内存
		return 1;
	}
	else
	{
		listnodeptr previousptr = *sptr;//保存地址
		listnodeptr currentptr = (*sptr)->nextptr;//寻找地址
												  //循环查找
		while (currentptr != NULL && currentptr->date != value)//当循环没到最尾，或者链表层中编号不等于输入值时
		{
			previousptr = currentptr;//保存地址
			currentptr = currentptr->nextptr;//进入下一层链表
		}
		if (currentptr != NULL)//找到时
		{
			listnodeptr temptr = currentptr;
			previousptr->nextptr = currentptr->nextptr;//将前一个链表的尾巴指向查到的链表的下一个层的地址
			free(temptr);//释放内存
			return 1;
		}
		else
		{
			printf("cannot be found the data %s\n", value);//找不到相关编号
		}
	}
	return'\0';
}

int isempty(listnodeptr sptr)//当头文件是空时
{
	return sptr == NULL;


}

void printlist(listnodeptr currentptr)//输出链表结构函数
{
	if (isempty(currentptr))//当头文件是空时
	{
		puts("list is empty");//链表为空

	}
	else
	{
		puts("list is");//链表是
		while (currentptr != NULL)//当当前链表地址不是空时
		{
			printf("%s-->", currentptr->date);//输出当前链表的编号
			currentptr = currentptr->nextptr;//进入下一层链表
		}
		puts("NULL\n");//尾地址是NULL
	}
}

int bigOrSmall(char *s1, char *s2)
{
	if (strcmp(s1, s2) > 0)
	{
		return 1;
	}
	return 0;
}